package Modelo;

import java.util.ArrayList;
import java.util.Iterator;

public class Amplitud {

	public ArrayList<Integer> amplitud(int[] vector) {
		/*
		 * Se crea las listas vacias ABIERTO Y CERRADO
		 */
		ArrayList flips = new ArrayList();
		ArrayList cerrado = new ArrayList();
		ArrayList abierto = new ArrayList();

		/*
		 * poner nodo inicial en ABIERTO
		 */
		Arbol padre = new Arbol();
		padre.setVector(vector);
		abierto.add(padre);
		/*
		 * Si hay nodos sucesores y no son nodo meta moverlos al final de
		 * abierto
		 */
		abierto = getListaAbiertoFinal(flips, cerrado, abierto);
		flips = ((Arbol) abierto.get(0)).getAnterior();
		return flips;
	}

	private boolean finalStatus(int[] vec) {
		boolean result = true;
		for (int i = 0; i < vec.length; i++) {
			if (vec[i] != i + 1) {
				result = false;
			}
		}
		return result;
	}

	private boolean closeExi(ArrayList<int[]> lista, int[] vector) {
		boolean result = false;
		for (int[] vec : lista) {
			int equals = 0;
			for (int i = 0; i < vector.length; i++) {
				if (vector[i] == vec[i])
					equals++;
			}
			if (equals == vector.length)
				result = true;
		}
		return result;
	}

	private ArrayList getListaAbiertoFinal(ArrayList flips, ArrayList cerrado,
			ArrayList abierto) {
		while (!finalStatus(((Arbol) abierto.get(0)).getVector())) {

			if (closeExi(cerrado, ((Arbol) abierto.get(0)).getVector())) {
				abierto.remove(0);
			} else {
				Arbol copy = (Arbol) abierto.get(0);
				int[] temp = ((Arbol) abierto.get(0)).getVector();
				abierto.remove(0);

				int[] vec = new int[temp.length];
				for (int p = 0; p < temp.length; p++) {
					vec[p] = temp[p];
				}
				/*
				 * Colocar el nodo en CERRADO
				 */
				cerrado.add(vec);

				/*
				 * Expandir el nodo obteniendo todos sus sucesores
				 */
				for (int pos = 1; pos < temp.length; pos++) {
					int[] rec = new int[temp.length];
					for (int p = 0; p < temp.length; p++) {
						rec[p] = temp[p];
					}
					int[] vfl = new int[pos + 1];
					int j = 0;
					for (int i = pos; i >= 0; j++) {
						vfl[j] = rec[i];
						i--;
					}
					for (int i = pos; i >= 0; i--) {
						rec[i] = vfl[i];
					}
					vec = new int[temp.length];
					for (int p = 0; p < temp.length; p++) {
						vec[p] = rec[p];
					}
					Arbol ap = new Arbol();
					ap.setVector(vec);
					for (Iterator localIterator = copy.getAnterior().iterator(); localIterator
							.hasNext();) {
						int m = ((Integer) localIterator.next()).intValue();
						ap.getAnterior().add(Integer.valueOf(m));
					}
					ap.getAnterior().add(Integer.valueOf(pos + 1));
					abierto.add(ap);
				}
			}

		}
		return abierto;
	}

}
